import time

import monitor.channel
import config.hardware
### 基于INA219实现电流、电压、功率采集 林恩德  2022.6.18
###INA219利用100mΩ的分流电阻实现电流采集
###微雪的采集版采用I2C通讯，包括4个采集通道，地址分别为：0x40,0x41,0x42,0x43
class UIPCollect():
    def __init__(self,channelAddrs=[]):
        self.channels = []
        self.channels.append(monitor.channel.INA219Channel(
            i2cbus=config.hardware.params.monitor.ChargeI2c.Port,
            addr = config.hardware.params.monitor.ChargeI2c.Addr))
        self.channels.append(monitor.channel.INA219Channel(
            i2cbus=config.hardware.params.monitor.DisChargeI2c.Port,
            addr = config.hardware.params.monitor.DisChargeI2c.Addr))
    ###根据地址列表，依次采集各个通道的电压、电流与功率值，返回到列表中
    def collect(self):
        result = []
        for channel in self.channels:
            channel.collect()
            result.append([channel.bus_voltage,
            channel.shunt_voltage,
            channel.current,
            channel.power])
        return result
###18650 电池状态采集，采用3通道，微雪电源板的I2C地址为0x42
class BatteryStateCollect():
    def __init__(self):
        self.channel =monitor.channel.INA219Channel(
            i2cbus=config.hardware.params.monitor.BatteryI2c.Port,
            addr=config.hardware.params.monitor.BatteryI2c.Addr)
        self.soc = 0
    ##计算电池的SOC
    def collect(self):
        self.channel.collect()
        return [self.channel.bus_voltage,
            self.channel.shunt_voltage,
            self.channel.current,
            self.channel.power,
            self.getSoc()]
    #计算电池的SOC值，简易算法，不稳定。特别是充放电切换时有大的波动        
    def  getSoc(self):
         soc = (self.channel.bus_voltage-6)/2.4*100
         if(soc<0): soc = 0
         if(soc>100): soc = 100
         return round(soc,1)
# 程序入口
if __name__ == '__main__':
    battery = BatteryStateCollect()
    try:
        while True:
            result = battery.collect()#loop()        #  调用循环函数
            print("电源状态：BusV{:3.3f}V ShuntV{:3.3f}mV,Current{:3.3f}mA,Power{:3.3}W,Soc{:2.1f}%"
                .format(result[0],result[1],result[2],result[3],result[4]))
            time.sleep(1)
    except KeyboardInterrupt:  #  当按下Ctrl+C时，将执行destroy()子程序。
        print("done")